home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <assert.h>
- #include <math.h>
- #import "Alexandra.h"
- #import "NewsgroupSet.h"
- #import "readline.h"
- #import "Newsgroup.h"
- #import "ArticleSetMatrix.h"
- #import "NNTP.h"
- #import "ArticleSet.h"
- #import "ArticleViewControl.h"
- #import <misckit/MiscSortedList.h>
- #import "descriptors.h"
- #import "response_codes.h"
- #import "NewsGroupSetBrowser.h"
- #import <misckit/MiscAppDefaults.h>
- #import "MatrixScroller.h"
-
- @implementation NewsgroupSet
-
-
- - init
- {
- [super init];
- myMList=[[MiscSortedList alloc] init];
- [myMList setSortEnabled:FALSE];
- [myMList setSortOrder:Misc_ASCENDING];
- [ERROR_MANAGER addObserver:self
- selector:@selector(dumpNewsrc:) forError:S15];
- [ERROR_MANAGER addObserver:self
- selector:@selector(updateNewsgroups)
- forError:ENOTEPrefsChanged2];
-
- unselAction=@selector(clearMatrix);
- return self;
- }
-
- - free
- {
- [myMList makeObjectsPerform:@selector(free)];
- [myMList free];
- [ERROR_MANAGER removeObserver:self forError:S15];
- [ERROR_MANAGER removeObserver:self forError:ENOTEPrefsChanged2];
-
- return [super free];
- }
-
- - scanNewsrcAndActive
- {
- char aGroup[255];
- int i,j;
- FILE *newsrc;
- Newsgroup *aNewsgroup;
- HashTable *positionInList;
- const char *home;
- const char *nntp_server;
- char *filename;
- char *buffer;
- int position;
- BOOL exists;
- Storage *array;
- newsgroupDesc *ngDesc;
- int statusCode;
-
-
- // compose name of newsrc file
- home=NXHomeDirectory();
- nntp_server=[nntpServer serverName];
- filename=(char *)malloc((strlen(home)+strlen(nntp_server)+12)*sizeof(char));
- strcpy(filename,home);
- strcat(filename,"/.");
- strcat(filename,nntp_server);
- strcat(filename,".newsrc");
-
- // open newsrc file, parse all lines and make newsgroup list
- exists=FALSE;
- newsrc=fopen(filename,"r");
- if(newsrc!=NULL){
- exists=TRUE;
- while(!feof(newsrc)){
- readline(newsrc);
- buffer=get_buffer();
- i=0;
- while(buffer[i]!='\0' && buffer[i]!=':' && buffer[i]!='!'){
- i++;
- }
- if(buffer[i]!='\0'){
- strncpy(aGroup,buffer,i);
- aGroup[i]='\0';
- aNewsgroup=[[[[Newsgroup alloc] initTextCell:aGroup] setBogus:TRUE] unsetTag];
- if((buffer[i+1]!='\0')&&(buffer[i+2]!='\0'))
- [aNewsgroup setReadList:(buffer+i+2)];
- else
- [aNewsgroup setReadList:""];
- if(buffer[i]==':')
- [aNewsgroup setSubscribed];
- [myMList addObject:aNewsgroup];
- }
- }
- }
- fclose(newsrc);
- free(filename);
-
- //put every newsgroupname in a hashtable
- j=[myMList count];
- positionInList=[[HashTable alloc] initKeyDesc:"*" valueDesc:"i" capacity:(int)floor(j*1.3)];
- for(i=0;i<j;i++)
- [positionInList insertKey:[[myMList objectAt:i] stringValue] value:(void *)i+1];
-
- //ISSUE LIST COMMAND
- //Slow link feature means don't do the "list" command
- if(([nntpServer slowLink])&&([nntpServer timeTag])&&(exists)){
- j=[myMList count];
- for(i=0;i<j;i++){
- aNewsgroup=[myMList objectAt:i];
- [[[aNewsgroup unsetTag] setBogus:FALSE] setPostable:'y'];
- if([aNewsgroup isSubscribed]==TRUE)
- if((statusCode=[nntpServer requestGroup:aNewsgroup])!=OK_GROUP){ //get min+max article
- [aNewsgroup setBogus:TRUE];
- }
- }
-
- //see if any new groups
- array=[[Storage alloc] initCount:0 elementSize:sizeof(newsgroupDesc) description:"{*llc}"];
- [nntpServer scanNewGroups:array];
- j=[array count];
- if(j>0) //new groups?
- for(i=0;i<j;i++){
- BOOL found;
- newsgroupDesc *aNGDesc=(newsgroupDesc *)[array elementAt:(unsigned)i];
- if([self lookupGroup:aNGDesc->groupname found:&found],found==FALSE){
- aNewsgroup=[[Newsgroup alloc] initTextCell:aNGDesc->groupname];
- [[[[[aNewsgroup setBogus:FALSE] setMin:aNGDesc->min] setMax:aNGDesc->max] setPostable:aNGDesc->post] setTag]; //set tag-> new group
- [myMList addObject:aNewsgroup];
- }
- }
- for(i=0;i<j;i++)
- free(((newsgroupDesc *)[array elementAt:(unsigned)i])->groupname);
- [array free];
- }
- else{ //NO SLOW LINK OR FIRST TIME PROGRAM WAS STARTED (NO TIMETAG)
- //get active newsgroups from nntp server
- array=[[Storage alloc] initCount:0 elementSize:sizeof(newsgroupDesc) description:"{*llc}"];
- [nntpServer scanActive:array];
- // parse active newsgroups
- j=[array count];
- for(i=0;i<j;i++){
- ngDesc=(newsgroupDesc *)[array elementAt:(unsigned)i];
- position=(int)[positionInList valueForKey:ngDesc->groupname];
- //new group?
- if(position==0){
- aNewsgroup=[[[Newsgroup alloc] initTextCell:ngDesc->groupname] setTag];
- [myMList addObject:aNewsgroup];
- }
- else
- aNewsgroup=[myMList objectAt:(position-1)]; // subtract one of position
- [[[[aNewsgroup setBogus:FALSE] setMin:ngDesc->min] setMax:ngDesc->max] setPostable:ngDesc->post];
- free(ngDesc->groupname);
- }
- [array free];
- }
-
- [positionInList free];
-
- //remove bogus and unvalid Newsgroups
- for(i=[myMList count]-1;i>=0;i--){
- id aNewsgroup=[myMList objectAt:i];
- if([aNewsgroup bogus] || strchr([aNewsgroup stringValue],':'))
- [[myMList removeObjectAt:i] free];
- }
-
- //approximate the number of unread articles in every group
- j=[myMList count];
- for(i=0;i<j;i++)
- [[myMList objectAt:i] approxNumUnread];
-
- //check for new newsgroups in newsgroup list (new ng <-> ng is taged)
- exists=FALSE;
- j=[myMList count];
- for(i=0;i<j;i++)
- if([[myMList objectAt:i] isTaged]==TRUE){
- exists=TRUE;
- break;
- }
-
- if(exists==TRUE)
- [myMatrix setButtonTitle:"New Newsgroups"]; //some new groups
- else{
- [myMatrix setButtonTitle:"Subscribed Newsgroups"]; //no new groups
- j=[myMList count];
- for(i=0;i<j;i++){
- aNewsgroup=[myMList objectAt:i];
- // setTag <-> newsgroup is visible in matrix <-> newsgroup is subscribed
- if([aNewsgroup isSubscribed]==TRUE)
- [aNewsgroup setTag];
- else
- [aNewsgroup unsetTag];
- }
- }
-
- return self;
- }
-
- - newGroups:sender
- {
- Storage *array;
- int i,j;
- newsgroupDesc *aNGDesc;
- Newsgroup *aNewsgroup;
- BOOL found;
-
- array=[[Storage alloc] initCount:0 elementSize:sizeof(newsgroupDesc) description:"{*llc}"];
-
- [nntpServer scanNewGroups:array];
-
- j=[array count];
- if(j==0){
- NXBeep();
- [myMatrix updateButtonTitle];
- }
- else{
- [myMList makeObjectsPerform:@selector(unsetTag)];
- [myMatrix setButtonTitle:"New Newsgroups"];
- for(i=0;i<j;i++){
- aNGDesc=(newsgroupDesc *)[array elementAt:(unsigned)i];
- if([self lookupGroup:aNGDesc->groupname found:&found],found==FALSE){
- aNewsgroup=[[Newsgroup alloc] initTextCell:aNGDesc->groupname];
- [[[[aNewsgroup setBogus:FALSE] setMin:aNGDesc->min] setMax:aNGDesc->max] setPostable:aNGDesc->post];
- [[aNewsgroup approxNumUnread] setTag];
- [myMList addObject:aNewsgroup];
- }
- }
- [[myMatrix reloadMatrix] display];
- [self sync];
- }
-
- j=[array count];
- for(i=0;i<j;i++)
- free(((newsgroupDesc *)[array elementAt:(unsigned)i])->groupname);
- [array free];
-
- return self;
- }
-
- -newNews:sender
- {
- int i,j;
- int statusCode;
- BOOL slowLink;
- id oldSelection;
- BOOL oldSelNewNews=FALSE;
- BOOL cellsRemoved=FALSE;
-
- j=[myMList count];
- if(j==0)
- return self;
- oldSelection=currentSelection;
-
- slowLink=[nntpServer slowLink];
- for(i=0;i<j;i++){
- Newsgroup *aGroup=[myMList objectAt:i];
- if(aGroup==nil) continue;
- if(([aGroup isSubscribed]==TRUE)||(aGroup==currentSelection)){
- long oldMax=[aGroup maxNumber];
- statusCode=[nntpServer requestGroup:aGroup];
- if(statusCode!=OK_GROUP){
- [myMatrix removeInvalidCell:aGroup andUpdate:FALSE];
- i--; //list length gets smaller
- j--;
- if(oldSelection==aGroup)
- oldSelection=nil;
- cellsRemoved=TRUE;
- }
- else{
- //BOOL setBack=TRUE;
- long newMax=[aGroup maxNumber];
- long diff=newMax-oldMax;
- if(diff>0){
- if(aGroup==oldSelection)
- oldSelNewNews=TRUE;
- if((slowLink==TRUE)&&([aGroup isDelayed]==TRUE)){
- [aGroup approxNumUnread];
- //setBack=FALSE;
- }
- else
- [aGroup incNumberUnreadArticles:(int)diff];
- }
- }
- }
- }
- if(cellsRemoved==TRUE)
- [myMatrix update];
-
- if(!strcmp([[myMatrix selectionButton] title],"Groups with Articles"))
- [self displayGroupsWithUnreadNews:self];
-
- if(currentSelection!=nil){
- statusCode=[nntpServer requestGroup:currentSelection];
- if(statusCode!=OK_GROUP){
- [myMatrix removeInvalidCell:currentSelection];
- return self;
- }
- if((oldSelNewNews==TRUE) && (currentSelection==oldSelection)){
- id artMatrix=[theArticleSet theMatrix];
- [currentSelection scanArticles:nntpServer visibleIn:artMatrix];
- [artMatrix reloadMatrix];
- [[[artMatrix display] window] flushWindow];
- [theArticleSet sync];
- }
- if(currentSelection!=oldSelection){
- currentSelection=nil;
- [self selectNewsgroup:self];
- }
- }
- if(cellsRemoved==FALSE)
- [myMatrix display];
-
- return self;
- }
-
- - updateNewsgroups
- {
- int i,j=[myMList count];
- for(i=0;i<j;i++)
- [[myMList objectAt:i] updateArticles];
-
- [theArticleSet redisplayMatrix];
- return self;
- }
- - dumpNewsrc:sender
- {
- int i,j;
- Newsgroup *aNewsgroup;
- char *filename,*oldfile;
- const char *home;
- const char *nntp_server;
- NXStream *nrcStream;
- const char *aString;
- char aChar;
-
- if([myMList count]==0)
- return self;
-
- nrcStream=NXOpenMemory(NULL,0,NX_READWRITE);
-
- j=[myMList count];
- for(i=0;i<j;i++){
- aNewsgroup=[myMList objectAt:i];
- aString=[aNewsgroup stringValue];
- NX_ASSERT([aNewsgroup stringValue]!=NULL,"Newsgroup without name");
- NXWrite(nrcStream,aString,strlen(aString));
- if([aNewsgroup isSubscribed]==TRUE)
- NXWrite(nrcStream,": ",2);
- else
- NXWrite(nrcStream,"! ",2);
- [aNewsgroup dumpReadList:nrcStream];
- NXSeek(nrcStream,(-1)*sizeof(char),NX_FROMCURRENT);
- if(NXRead(nrcStream,&aChar,sizeof(char)),aChar==' ')
- NXSeek(nrcStream,(-1)*sizeof(char),NX_FROMCURRENT);
- NXWrite(nrcStream,"\n",1);
- }
-
- //rename + save new
- home=NXHomeDirectory();
- i=strlen(home);
-
- nntp_server=[nntpServer serverName];
- j=strlen(nntp_server);
-
- filename=(char *)calloc(i+j+12,sizeof(char));
- sprintf(filename,"%s/.%s.newsrc",home,nntp_server);
-
- oldfile=(char *)malloc((strlen(filename)+2)*sizeof(char));
- strcpy(oldfile,filename);
- strcat(oldfile,"~");
- rename(filename,oldfile);
- free(oldfile);
-
- NXSaveToFile(nrcStream,filename);
- NXCloseMemory(nrcStream,NX_FREEBUFFER);
- free(filename);
-
- return self;
- }
-
- - displayAllGroups:sender
- {
- int i,j;
-
- j=[myMList count];
- for(i=0;i<j;i++)
- [[myMList objectAt:i] setTag];
- [[myMatrix reloadMatrix] display];
-
- [myMatrix setButtonTitle:"All Newsgroups"];
-
- return self;
- }
-
- - displaySubscribedGroups:sender
- {
- int i,j;
- Newsgroup *oldNG;
-
- j=[myMList count];
- for(i=0;i<j;i++){
- Newsgroup* aNewsgroup;
- aNewsgroup=[myMList objectAt:i];
- if([aNewsgroup isSubscribed])
- [aNewsgroup setTag];
- else
- [aNewsgroup unsetTag];
- }
- [[myMatrix reloadMatrix] display];
-
- oldNG=currentSelection;
- [self sync];
- if((numSelCells==1)&&(oldNG!=currentSelection)){
- currentSelection=oldNG;
- [self selectNewsgroup:self];
- }
-
- [myMatrix setButtonTitle:"Subscribed Newsgroups"];
-
- return self;
- }
-
- - displayGroupsWithUnreadNews:sender
- {
- int i,j;
- Newsgroup *oldNG;
-
- j=[myMList count];
- for(i=0;i<j;i++){
- Newsgroup* aNewsgroup;
- aNewsgroup=[myMList objectAt:i];
- if([aNewsgroup isSubscribed] && [aNewsgroup numberUnreadArticles]>0)
- [aNewsgroup setTag];
- else
- [aNewsgroup unsetTag];
- }
- if(currentSelection!=nil)
- [currentSelection setTag];
-
- [[myMatrix reloadMatrix] display];
-
- oldNG=currentSelection;
- [self sync];
- if((numSelCells==1)&&(oldNG!=currentSelection)){
- currentSelection=oldNG;
- [self selectNewsgroup:self];
- }
-
- [myMatrix setButtonTitle:"Groups with Articles"];
-
- return self;
- }
-
- - selectNewsgroup:sender
- {
- Newsgroup* oldNG;
-
- [[myMatrix window] makeFirstResponder:myMatrix];
- oldNG=currentSelection;
- [self sync];
-
- if(oldNG!=currentSelection)
- if(numSelCells==1){
- int statusCode=[nntpServer requestGroup:currentSelection];
- if(statusCode!=OK_GROUP){
- [myMatrix perform:@selector(removeInvalidCell:) with:currentSelection afterDelay:0.0 cancelPrevious:YES];
- return self;
- }
- [currentSelection scanArticles:nntpServer];
-
- [[theArticleSet theMatrix] setButtonTitle:"Unread Articles"];
- [theArticleSet loadGroup:currentSelection];
- [myMatrix display];
- [self dumpNewsrc:self];
- }
- else
- [nntpServer unselectCurrentGroup];
-
- return self;
- }
-
- - (BOOL)selectNewsgroupNamed:(const char *)gname
- {
- BOOL found;
- Newsgroup *aGroup;
- int position;
-
- position=[self lookupGroup:gname found:&found];
- if(!found)
- return FALSE;
-
- aGroup=[myMList objectAt:position];
- if(![aGroup isTaged])
- [self displayAllGroups:self];
-
- return [myMatrix selectNewsgroupNamed:gname];
- }
-
- - subscribeOrUnsubscribe:(BOOL)flag
- {
- /*flag==TRUE <=> subscribe */
- int i,j;
- List *selectionList=nil;
- Newsgroup *aNewsgroup;
-
- selectionList=[myMatrix getCurrSelections];
- j=[selectionList count];
- for(i=0;i<j;i++){
- aNewsgroup=[selectionList objectAt:i];
- if(flag==TRUE)
- [aNewsgroup setSubscribed];
- else
- [aNewsgroup setUnsubscribed];
- }
- [selectionList free];
- [myMatrix display];
- return self;
- }
-
- - subscribe:sender
- {
- [self subscribeOrUnsubscribe:TRUE];
- return self;
- }
-
- - unsubscribe:sender
- {
- [self subscribeOrUnsubscribe:FALSE];
- return self;
- }
-
- - markAllRead:sender
- {
- int i,j;
- id ng=[myMatrix getCurrSelections];
-
- j=[ng count];
- if(j==0){
- NXRunAlertPanel("ALEXANDRA","No newsgroup(s) selected.",NULL,NULL,NULL);
- return self;
- }
- else if(j>1){
- int r=NXRunAlertPanel("ALEXANDRA",
- "Catchup %d selected groups?",NULL,"Cancel",NULL,j);
- if(r==NX_ALERTALTERNATE)
- return self;
- }
-
- for(i=0;i<j;i++)
- [[ng objectAt:i] markAllReadUntil:nil];
-
- if(j==1)
- [theArticleSet redisplayMatrix];
- [myMatrix display];
-
- return self;
- }
-
- - markAllUntilSelRead:sender;
- {
- id ng=[myMatrix getCurrSelections];
-
- if([ng count]!=1)
- return self;
-
- [[ng objectAt:0] markAllReadUntil:[theArticleSet currentSelection]];
- [theArticleSet redisplayMatrix];
- [myMatrix display];
-
- return self;
- }
-
- - markAllClever:sender;
- {
- id selectedArticle;
- static time_t lastCatchup=0;
-
- if(!currentSelection)
- return [self markAllRead:self];
-
- selectedArticle=[theArticleSet currentSelection];
- if(!selectedArticle)
- [self markAllRead:sender];
- else{
- time_t now=time(NULL);
- if(now>lastCatchup+3)
- [self markAllUntilSelRead:self];
- else
- [self markAllRead:sender];
- lastCatchup=now;
- }
-
- return self;
- }
-
- - (int)lookupGroup:(const char *)aGroup found:(BOOL *)f
- {
- int cmpResult,j;
- Newsgroup *aNewsgroup;
-
- for(j=[myMList count]-1;j>=0;j--){
- aNewsgroup=[myMList objectAt:j];
- cmpResult=strcmp([aNewsgroup stringValue],aGroup);
- if(cmpResult==0){
- *f=TRUE;
- return j;
- }
- }
- *f=FALSE;
- return(0);
- }
-
- - shuffleList:(id)sourceCell to:(id)destCell
- {
- unsigned int from,to;
-
- from=[myMList indexOf:sourceCell];
- to=[myMList indexOf:destCell];
-
- NX_ASSERT(from!=NX_NOT_IN_LIST,"Internal DS mismatch");
- NX_ASSERT(to!=NX_NOT_IN_LIST,"Internal DS mismatch");
-
- [myMList removeObjectAt:from];
- [myMList insertObject:sourceCell at:to];
-
- return self;
- }
-
- - upOrDown:(int)delta
- {
- while([[theArticleSet theMatrix] selectNextCell:delta]==FALSE)
- if([myMatrix selectNextCell:delta]==FALSE){
- NXRunAlertPanel("ALEXANDRA","No more articles.",NULL,NULL,NULL);
- break;
- }
- return self;
- }
-
- - upOrDownOnePage:(int)delta
- {
- NXRect wholeBox;
- NXRect visibleBox;
- id theText=[theArticleViewControl theText];
-
- [theText getVisibleRect:&visibleBox];
- [theText getFrame:&wholeBox];
-
- if(((delta==-1) && NX_Y(&visibleBox)<=3.0) ||
- ((delta==1) && (NX_HEIGHT(&wholeBox) - NX_Y(&visibleBox) - NX_HEIGHT(&visibleBox))<=3.0))
- [self upOrDown:delta];
- else{
- NX_Y(&visibleBox)+=delta*(NX_HEIGHT(&visibleBox)*0.75);
- [theText scrollRectToVisible:&visibleBox];
- }
-
- return self;
- }
-
- - up:sender
- {
- [self upOrDown:-1];
- return self;
- }
-
- - down:sender
- {
- [self upOrDown:1];
- return self;
- }
-
- - upOnePage:sender
- {
- [self upOrDownOnePage:-1];
- return self;
- }
-
- - downOnePage:sender
- {
- [self upOrDownOnePage:1];
- return self;
- }
-
- - sortNewsgroupList:sender
- {
- [myMList unsort];
- [myMList sort];
- [myMatrix reloadMatrix];
- [myMatrix display];
-
- return self;
- }
-
- - switchToView:view
- {
- NXRect frame;
- id sview;
- id newOther,newMatrix;
- char *defaultViewerStr;
- const char *nntpname;
-
- if([myMatrix isKindOf:[NewsGroupSetBrowser class]]){
- newOther=myMatrix;
- newMatrix=[otherView docView];
- }
- else{
- newOther=[[myMatrix superview] superview];
- newMatrix=otherView;
- }
- sview=[newOther superview];
- [newOther getFrame:&frame];
-
- [newOther removeFromSuperview];
- [sview addSubview:otherView];
- [otherView setFrame:&frame];
- myMatrix=newMatrix;
- [myMatrix loadMatrix];
-
- if(currentSelection!=nil)
- if([myMatrix isKindOf:[NewsGroupSetBrowser class]]){
- const char *selName=[currentSelection stringValue];
- char *path=(char *)malloc((strlen(selName)+2)*sizeof(char));
- sprintf(path,".%s",selName);
- [[myMatrix window] disableFlushWindow];
- [myMatrix setAutodisplay:NO];
- [myMatrix setPath:path];
- [[myMatrix setAutodisplay:YES] display];
- [[[myMatrix window] reenableFlushWindow] flushWindow];
- free(path);
- }
- else{
- [otherView display];
- [myMatrix selectCell:currentSelection];
- }
- else
- [otherView display];
- otherView=newOther;
-
- nntpname=[nntpServer serverName];
- defaultViewerStr=(char *)malloc((strlen(nntpname)+21)*sizeof(char));
- sprintf(defaultViewerStr,"BrowserViewEnabled %s",nntpname);
- if([otherView isKindOf:[NewsGroupSetBrowser class]])
- [NXApp setDefault:defaultViewerStr toBool:NO];
- else
- [NXApp setDefault:defaultViewerStr toBool:YES];
- free(defaultViewerStr);
-
- return self;
- }
-
- - switchToListView:sender
- {
- if([myMatrix isKindOf:[NewsGroupSetBrowser class]]){
- id aCell;
- [self switchToView:otherView];
- if((aCell=[myMatrix selectedCell])!=nil)
- [myMatrix scrollCellToVisible:[[myMatrix cellList] indexOf:aCell]
- upperOffset:1.5 lowerOffset:1.5];
- }
- return self;
- }
-
- - switchToBrowserView:sender
- {
- if(![myMatrix isKindOf:[NewsGroupSetBrowser class]]){
- [self switchToView:otherView];
- [myMatrix scrollSelectionToVisible];
- }
- return self;
- }
-
-
-
- - (BOOL)selectViewCellEnabled:menuCell
- {
- if([menuCell action]==@selector(switchToListView:) &&
- ([myMatrix isKindOf:[NewsGroupSetBrowser class]]))
- return TRUE;
- if([menuCell action]==@selector(switchToBrowserView:) &&
- (![myMatrix isKindOf:[NewsGroupSetBrowser class]]))
- return TRUE;
- return FALSE;
- }
-
-
- - (BOOL)selectURL:(const char *)urlstring
- {
- BOOL success=FALSE;
- BOOL apanelWasRunning=FALSE;
-
- char *groupname=NULL;
- long seqnumber=0;
- char *msgid=NULL;
- BOOL isNewsURL=FALSE;
- char *buf1,*buf2,*buf3;
-
- if(!urlstring)
- return FALSE;
-
- buf1=NXCopyStringBuffer(urlstring);
-
- // nntp or news url?
- buf2=strstr(buf1,"news:");
- if(buf2){
- success=TRUE;
- isNewsURL=TRUE;
- buf2+=5;
- }
- else{
- buf2=strstr(buf1,"nntp:");
- if(buf2){
- success=TRUE;
- isNewsURL=FALSE;
- buf2+=5;
- }
- }
-
- if(!success){
- NXRunAlertPanel("Service","No valid URL.",NULL,NULL,NULL);
- apanelWasRunning=TRUE;
- }
-
- if(success){
-
- [[myMatrix window] makeKeyAndOrderFront:self];
-
- //skip any / or < chars
- while(*buf2=='/' || *buf2=='<')
- buf2++;
-
- //get useful string
- buf3=strpbrk(buf2,"\t >\r\n");
- if(buf3)
- *buf3='\0';
-
- if(isNewsURL){
- if(strchr(buf2,'@')){ // message-id news url
- char **groups;
-
- // first compose real messageid
- msgid=malloc((strlen(buf2)+4)*sizeof(char));
- strcpy(msgid,"<");
- strcat(msgid,buf2);
- strcat(msgid,">");
-
- // get all groupnames
- success=[nntpServer findArticle:msgid inGroups:&groups];
- if(!success){
- NXRunAlertPanel("Service","Article not available.",NULL,NULL,NULL);
- apanelWasRunning=TRUE;
- }
-
- //find all group objects
- if(success){
- char **gp=groups;
- MiscSortedList *groupList=[[MiscSortedList alloc] init];
- [groupList setSortEnabled:NO];
- [groupList setSortOrder:Misc_ASCENDING];
- while(*gp){
- BOOL found=FALSE;
- int pos=[self lookupGroup:*gp found:&found];
- if(found)
- [groupList addObject:[myMList objectAt:pos]];
- free(*gp);
- gp++;
- }
-
- // find best group
- if([groupList count]==0){
- success=FALSE;
- NXRunAlertPanel("Service","There's no such article available.",NULL,NULL,NULL);
- apanelWasRunning=TRUE;
- }
- else{
- int oldStype=[Newsgroup sortType];
- [Newsgroup setSortType:SORT_BY_SELECT_PRIORITY];
- [groupList sort];
- [Newsgroup setSortType:oldStype];
- groupname=NXCopyStringBuffer([[groupList objectAt:0] stringValue]);
- }
- [groupList free];
- }
- }
- else{
- groupname=NXCopyStringBuffer(buf2);
- }
- }
- else{
- char *t;
- if(t=strchr(buf2,'/')){
- *t='\0';
- groupname=NXCopyStringBuffer(buf2);
- seqnumber=atol(t+1);
- }
- else{
- success=FALSE;
- NXRunAlertPanel("Service","No valid URL.",NULL,NULL,NULL);
- apanelWasRunning=TRUE;
- }
- }
- }
-
- if(success){
-
- // select group
- success=[self selectNewsgroupNamed:groupname];
- if(!success){
- NXRunAlertPanel("Service","There's no newsgroup named '%s'.",NULL,NULL,NULL,groupname);
- apanelWasRunning=TRUE;
- }
- }
-
- if(success){
-
- // select article
- if(isNewsURL && msgid)
- success=[theArticleSet selectArticleWithMsgid:msgid];
- else if(!isNewsURL && seqnumber>0)
- success=[theArticleSet selectArticleWithNumber:seqnumber];
- if(!success){
- NXRunAlertPanel("Service","Could not find article.",NULL,NULL,NULL);
- apanelWasRunning=TRUE;
- }
- }
-
- if(groupname) free(groupname);
- if(msgid) free(msgid);
- if(buf1) free(buf1);
-
- if(!success && !apanelWasRunning)
- NXRunAlertPanel("Service","Could not perform service.",NULL,NULL,NULL);
-
- return success;
- }
-
-
- @end
-